package com.catsic.practice.service;

import com.catsic.practice.entity.ApprovalRecordEntity;
import com.catsic.practice.entity.LeaveApplicationEntity;
import com.catsic.practice.entity.TaskDTO;
import com.catsic.practice.mapper.ApprovalRecordRepository;
import com.catsic.practice.mapper.LeaveApplicationRepository;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author: zhangzf
 * @CreateTime: 2025-10-27  17:47
 * @Description: 服务层
 */

@Service
@Slf4j
public class ThirdLeaveProcessService {

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private LeaveApplicationRepository leaveApplicationRepository;

    @Autowired
    private ApprovalRecordRepository approvalRecordRepository;

    /**
     * 启动请假流程
     */
    @Transactional
    public ProcessInstance startLeaveProcess(LeaveApplicationEntity leaveApplication){
        // 设置流程变量
        Map<String, Object> variables = new HashMap<>();
        variables.put("student", leaveApplication.getApplyUser());
        variables.put("applyUser", leaveApplication.getApplyUser());
        variables.put("leaveDays", leaveApplication.getLeaveDays());
        variables.put("leaveReason", leaveApplication.getLeaveReason());
        //启动流程
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("three_level-leave-process",variables);
        List<Task> tasks = taskService.createTaskQuery()
                .processInstanceId(processInstance.getProcessInstanceId())
                .list();
        tasks.stream().forEach(t -> {
            log.info("任务ID: {}, 任务名称: {}, 办理人: {}, 候选人: {}",
                    t.getId(), t.getName(), t.getAssignee());
        });
        // 更新申请记录
        leaveApplication.setProcessInstanceId(processInstance.getId());
        leaveApplication.setStatus("审批中");
        leaveApplication.setCreateTime(new Date());
        leaveApplicationRepository.save(leaveApplication);
        log.info("请假流程启动成功，流程实例ID: {}", processInstance.getId());
        return processInstance;

    }

    /**
     * 学生提交申请到一级主管审批
     */
    @Transactional
    public Map<String, Object> submitToInstructor(String taskId, String instructor){
        Map<String, Object> result = new HashMap<>();
        try{
            log.info("=== 学生提交到一级主管开始 ===");
            log.info("任务ID: {}, 一级主管: {}", taskId, instructor);
            // 1. 验证任务存在且当前用户有权办理
            Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
            if (task == null) {
                throw new RuntimeException("任务不存在: " + taskId);
            }
            log.info("找到任务: {} (办理人: {})", task.getName(), task.getAssignee());
            // 2. 设置流程变量
            Map<String, Object> variables = new HashMap<>();
            variables.put("instructor", instructor);
            // 3. 完成任务
            taskService.complete(taskId, variables);
            result.put("success", true);
            result.put("message", "提交成功");
        }catch (Exception e){
            log.error("提交到一级主管失败", e);
            result.put("success", false);
            result.put("message", "提交失败: " + e.getMessage());
        }
        return result;
    }

    /**
     * 获取用户待办任务
     */
    public List<TaskDTO> getUserTasks(String assignee) {
        List<Task> tasks = taskService.createTaskQuery().orderByTaskCreateTime().taskCandidateOrAssigned(assignee).desc().list()
                .stream().collect(Collectors.toMap(Task::getId, task -> task, (existing, replacement) -> existing)).values().stream().collect(Collectors.toList());
        return tasks.stream().map(TaskDTO::fromTask).collect(Collectors.toList());
    }

    /**
     * 获取用户候选任务
     */
    public List<TaskDTO> getUserCandidates(String candidateUser) {
        List<Task> tasks = taskService.createTaskQuery().orderByTaskCreateTime().taskCandidateUser(candidateUser).desc().list()
                .stream().collect(Collectors.toMap(Task::getId, task -> task, (existing, replacement) -> existing)).values().stream().collect(Collectors.toList());
        return tasks.stream().map(TaskDTO::fromTask).collect(Collectors.toList());
    }


    /**
     * 一级主管审批
     */
    @Transactional
    public void firstApproval(String taskId, String decision, String comment, String headTeacher) {
        Map<String, Object> variables = new HashMap<>();
        variables.put("firstApprovalResult", decision);
        variables.put("headTeacher", headTeacher);

        taskService.complete(taskId, variables);

        // 保存审批记录
        saveApprovalRecord(taskId, "一级主管审批", decision, comment, headTeacher);
        // 更新申请状态
        updateApplicationStatusByTask(taskId, decision, "FIRST");

        log.info("一级主管审批完成，任务ID: {}, 审批结果: {}", taskId, decision);
    }

    /**
     * 二级主管审批
     */
    @Transactional
    public void secondApproval(String taskId, String decision, String comment, String director) {
        Map<String, Object> variables = new HashMap<>();
        variables.put("secondApprovalResult", decision);
        variables.put("director", director);

        taskService.complete(taskId, variables);

        // 保存审批记录
        saveApprovalRecord(taskId, "二级主管审批", decision, comment, director);

        // 更新申请状态
        updateApplicationStatusByTask(taskId, decision, "SECOND");

        log.info("二级主管审批完成，任务ID: {}, 审批结果: {}", taskId, decision);
    }

    /**
     * 三级主管审批
     */
    @Transactional
    public void thirdApproval(String taskId, String decision, String comment) {
        Map<String, Object> variables = new HashMap<>();
        variables.put("thirdApprovalResult", decision);

        taskService.complete(taskId, variables);

        // 保存审批记录
        saveApprovalRecord(taskId, "三级主管审批", decision, comment, null);

        // 更新申请状态
        updateApplicationStatusByTask(taskId, decision, "THIRD");

        log.info("三级主管审批完成，任务ID: {}, 审批结果: {}", taskId, decision);
    }


    /**
     * 保存审批记录
     */
    private void saveApprovalRecord(String taskId, String taskName, String decision, String comment, String nextApprover) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();

        ApprovalRecordEntity record = new ApprovalRecordEntity();
        record.setProcessInstanceId(task.getProcessInstanceId());
        record.setTaskId(taskId);
        record.setTaskName(taskName);
        record.setApprover(task.getAssignee());
        record.setDecision(decision);
        record.setComment(comment);
        record.setNextApprover(nextApprover);
        record.setApprovalTime(new java.util.Date());

        approvalRecordRepository.save(record);
    }

    /**
     * 更新申请状态
     */
    private void updateApplicationStatusByTask(String taskId, String decision, String approvalLevel) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        String processInstanceId = task.getProcessInstanceId();

        LeaveApplicationEntity application = leaveApplicationRepository.findByProcessInstanceId(processInstanceId)
                .orElseThrow(() -> new RuntimeException("申请记录不存在"));

        // 设置审批结果
        switch (approvalLevel) {
            case "FIRST":
                application.setFirstApprovalResult(decision);
                break;
            case "SECOND":
                application.setSecondApprovalResult(decision);
                break;
            case "THIRD":
                application.setThirdApprovalResult(decision);
                break;
        }

        // 更新总体状态
        if ("reject".equals(decision)) {
            application.setStatus("REJECTED");
        } else if ("THIRD".equals(approvalLevel) && "approve".equals(decision)) {
            application.setStatus("APPROVED");
        } else {
            application.setStatus("PROCESSING");
        }

        leaveApplicationRepository.save(application);
    }

    /**
     * 获取流程历史
     */
    public List<ApprovalRecordEntity> getProcessHistory(String processInstanceId) {
        return approvalRecordRepository.findByProcessInstanceId(processInstanceId);
    }

    /**
     * 获取任务详情
     */
    public TaskDTO getTaskById(String taskId) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        return TaskDTO.fromTask(task);
    }
}
